Typical HAL I2S use cases for migration

This section provides information about typical HAL I2S use cases for migration.

Note

The HAL I2S transmit and receive APIs are almost the same between HAL1 and HAL2. The only differences are:

  • Minor naming change: functions are now named HAL_I2S_ instead of HAL_I2SEx_.

  • The data buffer is now passed as a pointer to void instead of a pointer to a specific data type.

  • The processes for transmitting and receiving data using polling, interrupt, or DMA are the same in HAL1 and HAL2, except for the specification of buffer size.

Use case: I2S full duplex Tx/Rx in polling mode

This use case shows how to perform a full-duplex transmit/receive using polling.

Sequence diagram

@startuml
participant "Application" as App
participant "I2S" as I2S

== Full-duplex Tx/Rx Polling mode ==
App -> I2S: HAL_I2S_Init()
App -> I2S: HAL_I2SEx_TransmitReceive()

@enduml

Code snippet

HAL1

HAL2

I2S_HandleTypeDef hi2s;
uint8_t aTxBuffer[] = "****SPI - Two Boards communication based on Polling ****";
uint8_t aRxBuffer[BUFFERSIZE];

hI2S.Instance = SPI1;
hI2S.Init.Mode               = I2S_MODE_MASTER_FULLDUPLEX;
hI2S.Init.Standard           = I2S_STANDARD_MSB;
hI2S.Init.WSInversion        = I2S_WS_INVERSION_DISABLE;
hI2S.Init.DataFormat         = I2S_DATAFORMAT_24B;
hI2S.Init.MCLKOutput         = I2S_MCLKOUTPUT_DISABLE;
hI2S.Init.AudioFreq          = I2S_AUDIOFREQ_192K;
hI2S.Init.FirstBit           = I2S_FIRSTBIT_MSB;
hI2S.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_LEFT;
hI2S.Init.MasterKeepIOState  = I2S_MASTER_KEEP_IO_STATE_DISABLE;
hI2S.Init.CPOL               = I2S_CPOL_LOW;
HAL_I2S_Init(&hi2s);

HAL_I2SEx_TransmitReceive(&hi2s, aTxBuffer,
                          aRxBuffer, BUFFERSIZE, 5000);
hal_i2s_handle_t hi2s;
hal_i2s_config_t i2s_config;
uint8_t aTxBuffer[] = "****SPI - Two Boards communication based on Polling ****";
uint8_t aRxBuffer[BUFFERSIZE];

HAL_I2S_Init(hi2s, HAL_I2S1);
i2s_config.mode            = HAL_I2S_MODE_MASTER_FULL_DUPLEX;
i2s_config.standard        = HAL_I2S_STANDARD_MSB;
i2s_config.data_format     = HAL_I2S_DATA_FORMAT_24_BIT;
i2s_config.audio_frequency = HAL_I2S_AUDIO_FREQ_192_KHZ;
i2s_config.clock_polarity  = HAL_I2S_CLOCK_POLARITY_LOW;
i2s_config.first_bit       = HAL_I2S_MSB_FIRST;
HAL_I2S_SetConfig(&hi2s, &i2s_config);

HAL_I2S_TransmitReceive(&hi2s, aTxBuffer,
                        aRxBuffer, BUFFERSIZE, 5000);

Key changes

  1. HAL2 configures I2S via HAL_I2S_SetConfig() before starting the transfer.

  2. HAL2 uses the renamed API HAL_I2S_TransmitReceive() instead of HAL_I2SEx_TransmitReceive().

  3. HAL2 uses a void * data buffer pointer and uses a size expressed in bytes.


Use case: I2S full duplex Tx/Rx in interrupt mode

This use case shows how to perform a full-duplex transmit/receive using interrupts.

Sequence diagram

@startuml
participant "Application" as App
participant "I2S" as I2S
participant "I2Sx-IRQHandler" as irq

== Full-duplex Tx/Rx IT mode ==

App -> I2S: HAL_I2S_Init()
App -> I2S: HAL_I2SEx_TransmitReceive_IT()

"irq" <- : I2Sx interrupt1
irq -> I2S: HAL_I2S_IRQHandler()
"irq" <- : I2Sx interrupt2
irq -> I2S: HAL_I2S_IRQHandler()
"irq" <- : I2Sx interrupt3
irq -> I2S: HAL_I2S_IRQHandler()

I2S -> App: HAL_I2SEx_TxRxCpltCallback()
@enduml

Code snippet

HAL1

HAL2

I2S_HandleTypeDef hi2s;
uint8_t aTxBuffer[] = "****SPI - Two Boards communication based on Polling ****";
uint8_t aRxBuffer[BUFFERSIZE];

hI2S.Instance = SPI1;
hI2S.Init.Mode               = I2S_MODE_MASTER_FULLDUPLEX;
hI2S.Init.Standard           = I2S_STANDARD_MSB;
hI2S.Init.WSInversion        = I2S_WS_INVERSION_DISABLE;
hI2S.Init.DataFormat         = I2S_DATAFORMAT_24B;
hI2S.Init.MCLKOutput         = I2S_MCLKOUTPUT_DISABLE;
hI2S.Init.AudioFreq          = I2S_AUDIOFREQ_192K;
hI2S.Init.FirstBit           = I2S_FIRSTBIT_MSB;
hI2S.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_LEFT;
hI2S.Init.MasterKeepIOState  = I2S_MASTER_KEEP_IO_STATE_DISABLE;
hI2S.Init.CPOL               = I2S_CPOL_LOW;
HAL_I2S_Init(&hi2s);

HAL_I2SEx_TransmitReceive_IT(&hi2s, aTxBuffer,
                             aRxBuffer, BUFFERSIZE, 5000);
hal_i2s_handle_t hi2s;
hal_i2s_config_t i2s_config;
uint8_t aTxBuffer[] = "****SPI - Two Boards communication based on Polling ****";
uint8_t aRxBuffer[BUFFERSIZE];

HAL_I2S_Init(hi2s, HAL_I2S1);
i2s_config.mode            = HAL_I2S_MODE_MASTER_FULL_DUPLEX;
i2s_config.standard        = HAL_I2S_STANDARD_MSB;
i2s_config.data_format     = HAL_I2S_DATA_FORMAT_24_BIT;
i2s_config.audio_frequency = HAL_I2S_AUDIO_FREQ_192_KHZ;
i2s_config.clock_polarity  = HAL_I2S_CLOCK_POLARITY_LOW;
i2s_config.first_bit       = HAL_I2S_MSB_FIRST;
HAL_I2S_SetConfig(&hi2s, &i2s_config);

HAL_I2S_TransmitReceive_IT(&hi2s, aTxBuffer,
                           aRxBuffer, BUFFERSIZE);

Key changes

  1. HAL2 uses HAL_I2S_SetConfig() before starting the transfer.

  2. HAL2 uses the renamed API HAL_I2S_TransmitReceive_IT() instead of HAL_I2SEx_TransmitReceive_IT().

  3. HAL2 uses HAL_I2S_TxRxCpltCallback() (renamed from HAL_I2SEx_TxRxCpltCallback()).


Use case: I2S transmission in DMA mode

This use case shows how to start an I2S transmit operation using DMA and handle half-complete and complete callbacks.

Sequence diagram

@startuml
participant "Application" as App
participant "I2S" as I2S
participant "DMA" as DMA
participant "DMAx-IRQHandler" as irq


App -> I2S: HAL_I2S_Init()
App -> I2S: HAL_I2S_Transmit_DMA()

I2S -> DMA: HAL_DMA_Start_IT()
"irq" <- : DMAx half complete interrupt
irq -> DMA: HAL_DMA_IRQHandler()
DMA -> I2S: XferHalfCpltCallback()
I2S -> App: HAL_I2S_TxHalfCpltCallback()

"irq" <- : DMAx complete interrupt
irq -> DMA: HAL_DMA_IRQHandler()
DMA -> I2S: XferCpltCallback()
I2S -> App: HAL_I2S_TxCpltCallback()
@enduml

Code snippet

HAL1

HAL2

I2S_HandleTypeDef hi2s;
uint8_t aTxBuffer[] = "****SPI - Two Boards communication based on Polling ****";
uint8_t aRxBuffer[BUFFERSIZE];

hI2S.Instance = SPI1;
hI2S.Init.Mode               = I2S_MODE_MASTER_TX;
hI2S.Init.Standard           = I2S_STANDARD_MSB;
hI2S.Init.WSInversion        = I2S_WS_INVERSION_DISABLE;
hI2S.Init.DataFormat         = I2S_DATAFORMAT_24B;
hI2S.Init.MCLKOutput         = I2S_MCLKOUTPUT_DISABLE;
hI2S.Init.AudioFreq          = I2S_AUDIOFREQ_192K;
hI2S.Init.FirstBit           = I2S_FIRSTBIT_MSB;
hI2S.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_LEFT;
hI2S.Init.MasterKeepIOState  = I2S_MASTER_KEEP_IO_STATE_DISABLE;
hI2S.Init.CPOL               = I2S_CPOL_LOW;
HAL_I2S_Init(&hi2s);

__HAL_LINKDMA(hi2s, hdmatx, handle_GPDMA1_Channel1);
HAL_I2S_Transmit_DMA(&hi2s, aTxBuffer, BUFFERSIZE);
hal_i2s_handle_t hi2s;
hal_i2s_config_t i2s_config;
uint8_t aTxBuffer[] = "****SPI - Two Boards communication based on Polling ****";
uint8_t aRxBuffer[BUFFERSIZE];

HAL_I2S_Init(hi2s, HAL_I2S1);
i2s_config.mode            = HAL_I2S_MODE_MASTER_TX;
i2s_config.standard        = HAL_I2S_STANDARD_MSB;
i2s_config.data_format     = HAL_I2S_DATA_FORMAT_24_BIT;
i2s_config.audio_frequency = HAL_I2S_AUDIO_FREQ_192_KHZ;
i2s_config.clock_polarity  = HAL_I2S_CLOCK_POLARITY_LOW;
i2s_config.first_bit       = HAL_I2S_MSB_FIRST;
HAL_I2S_SetConfig(&hi2s, &i2s_config);

HAL_I2S_SetTxDMA(&hi2s, &hGPDMA1_CH1);
HAL_I2S_Transmit_DMA(&hi2s, aTxBuffer, BUFFERSIZE);

Key changes

  1. HAL2 configures I2S via HAL_I2S_SetConfig() before starting the transfer.

  2. HAL2 links the Tx DMA handle to the I2S handle using HAL_I2S_SetTxDMA().